<?php

class EmptyBlocListForm extends BaseUserForm
{

    const NAME = 'blocuri';
    const WRAPPER_NAME = 'list';

    public function __construct($object = null, $options = array(), $CSRFSecret = null)
    {
        parent::__construct(sfContext::getInstance()->getUser()->getObject(), $options, $CSRFSecret);
    }

    public function configure()
    {
        // this form is only a wrapper form
        $this->useFields();
        $this->getWidgetSchema()->setNameFormat(self::NAME . '[%s]');

        // numarul de blocuri care sunt afisate in formular
        $blocRows = min(array($this->getOption('bloc_rows', sfConfig::get('mod_apartamente_empty_bloc_rows')), sfConfig::get('mod_apartamente_empty_bloc_rows')));

        // embed BlocForm forms
        $this->addEmptyBlocForms(range(0, $blocRows - 1));

        // se adauga un pre-validator
        $this->mergePreValidator(new EmptyBlocListPreValidator());

        // se adauga un post-validator
        $this->mergePostValidator(new EmptyBlocListPostValidator());
    }

    /**
     * Se sterg din formular blocurile si scarile necompletate.
     * Se adauga, dupa caz, noi sub-formulare (bloc, scara)
     *
     * @param array $taintedValues
     * @param array $taintedFiles
     */
    public function bindAndSave(array $taintedValues = null, array $taintedFiles = null)
    {
        //$blocList = $this->getValue(self::WRAPPER_NAME);
        // se vor memora blocurile completate, urmand ca celelalte sa fie eliminate din formular
        $usedKeys = array();
        $count = 0;
        $maxAvailableBlocuri = BlocPeer::getMaxAvailableBlocuri();

        $wrapperForm = $this->embeddedForms[self::WRAPPER_NAME];
        $isModified = false;

        foreach ($taintedValues[self::WRAPPER_NAME] as $blocKey => $blocValue)
        {
            // daca blocul nu exista in formular, se adauga
            if (!isset($this[self::WRAPPER_NAME][$blocKey]))
            {
                $this->addEmptyBlocForms(array($blocKey));
            }

            // verific scarile pentru blocul curent:
            // pe cele necompletate le elimin din formular, iar pe cele care nu exista in formular, dar sunt completate, le adaug
            $blocWrapperForm = $wrapperForm->embeddedForms[$blocKey];
            $addNewScara = array();
            foreach ($blocValue[EmptyBlocForm::WRAPPER_NAME] as $scaraKey => $scaraValue)
            {
                if (strlen(trim($scaraValue['name'])) > 0)
                {
                    if (!isset($this[self::WRAPPER_NAME][$blocKey][EmptyBlocForm::WRAPPER_NAME][$scaraKey]))
                    {
                        $addNewScara[] = $scaraKey;
                    }
                }
                else
                {
                    // elimin scara din formular
                    unset($taintedValues[self::WRAPPER_NAME][$blocKey][EmptyBlocForm::WRAPPER_NAME][$scaraKey]);

                    Forms::delete($this, array(self::WRAPPER_NAME, $blocKey, EmptyBlocForm::WRAPPER_NAME, $scaraKey));
                }
            }

            // adaug scarile in formular
            $blocWrapperForm->addEmptyScaraForm($addNewScara);


            // daca denumirea blocului si nici o scara nu sunt completate, blocul se elimina din formular
            // totodata se elimina din formular si blocurile care sunt in plus
            if (strlen(trim($taintedValues[self::WRAPPER_NAME][$blocKey]['name'])) == 0
                    && count($taintedValues[self::WRAPPER_NAME][$blocKey][EmptyBlocForm::WRAPPER_NAME]) == 0
                    || ++$count > $maxAvailableBlocuri)
            {
                $addNewScara = false;
                unset($taintedValues[self::WRAPPER_NAME][$blocKey]);
                Forms::delete($this, array(self::WRAPPER_NAME, $blocKey));
            }
            else
            {
                $usedKeys[$blocKey] = true;
            }

            // daca au fost adaugate noi scari, se actualizeaza sub-form-ul care contine scarile
            if ($addNewScara)
            {
                $isModified = true;
                $wrapperForm->embedForm($blocKey, $blocWrapperForm);
            }
        }

        // daca a avut loc o modificare (adaugare) asupra sub-form-urilor, se actualizeaza intregul sub-form principal
        if ($isModified)
        {
            $this->embedForm(self::WRAPPER_NAME, $wrapperForm);
        }

        // pastrez doar sub-form-urile care sunt completate
        foreach ($this->embeddedForms[self::WRAPPER_NAME] as $blocKey => $ef)
        {
            if (empty($usedKeys[$blocKey]))
            {
                Forms::delete($this, array(self::WRAPPER_NAME, $blocKey));
            }
        }

        return parent::bindAndSave($taintedValues, $taintedFiles);
    }

    protected function addEmptyBlocForms($names)
    {
        $names = (array) $names;
        $wrapperForm = @$this->embeddedForms[self::WRAPPER_NAME];
        if ($wrapperForm === null)
        {
            $wrapperForm = new sfForm();
            $this->embedForm(self::WRAPPER_NAME, $wrapperForm);
        }
        foreach ($names as $name)
        {
            $wrapperForm->embedForm($name, new EmptyBlocForm(null, array('scara' => $this->getOption('scara'))));
        }

        $this->embedForm(self::WRAPPER_NAME, $wrapperForm);
    }

}
